const CryptoJS = require('crypto-js')
const Ursa = require('ursa')

class crypto {

	constructor(params) {
		Object.assign(this, params)
		this.rsaKey = Ursa.createPrivateKey(this.privateKey)
		this.rsaDataKey = Ursa.createPrivateKey(this.dataPrivateKey)
	}

	encryptAES(data, key, iv) {
		try {
			data = CryptoJS.enc.Utf8.parse(data)
			key = CryptoJS.enc.Utf8.parse(key)
			iv = CryptoJS.enc.Utf8.parse(iv)
			const encrypted = CryptoJS.AES.encrypt(data, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
			return encrypted.toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1068', msg:'encrypt data failed'}
		}
	}

	decryptAES(data, key, iv) {
		try {
			key = CryptoJS.enc.Utf8.parse(key)
			iv = CryptoJS.enc.Utf8.parse(iv)
			const decrypted = CryptoJS.AES.decrypt(data, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
			const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8)
			return decryptedStr.toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1069', msg:'decrypt data failed'}
		}
	}

	decryptWxData(wxEncrypytedData, sessionKey, wxIv) {
		try {
			console.log('加密数据', wxEncrypytedData, sessionKey, wxIv)
			sessionKey = CryptoJS.enc.Base64.parse(sessionKey)
			wxIv = CryptoJS.enc.Base64.parse(wxIv)
			let decodedData = CryptoJS.AES.decrypt(wxEncrypytedData, sessionKey, {
				iv: wxIv,
				mode: CryptoJS.mode.CBC,
				padding: CryptoJS.pad.Pkcs7
			})
			decodedData = JSON.parse(decodedData.toString(CryptoJS.enc.Utf8))
			return decodedData
		}
		catch(err) {
			console.error(err)
			throw {code:'-1069', msg:'decrypt data failed'}
		}
	}

	//使用公钥加密数据
	encryptRSA(data) {
		return this.rsaKey.encrypt(data, 'base64', Ursa.RSA_PKCS1_PADDING)
	}

	//使用私钥解密数据
	decryptRSA(data) {
		return this.rsaKey.decrypt(data, 'base64', 'utf8', Ursa.RSA_PKCS1_PADDING)
	}

	//使用私钥加密数据
	encryptPrivateRSA(data) {
		return this.rsaKey.privateEncrypt(data, 'utf8', 'base64', Ursa.RSA_PKCS1_PADDING)
	}

	//使用公钥解密数据
	decryptPublicRSA() {
		return this.rsaKey.publicDecrypt(data, 'base64', 'utf8', Ursa.RSA_PKCS1_PADDING)
	}

	//解密数据密钥
	decryptDataKey(dataKey) {
		return this.rsaDataKey.decrypt(dataKey, 'base64', 'utf8', Ursa.RSA_PKCS1_PADDING)
	}

	encryptHMAC(data, key) {
		console.log(CryptoJS.HmacSHA1(data, key))
		return CryptoJS.HmacSHA1(data, key).toString(CryptoJS.enc.Base64)
	}

	encodeBase64(data) {
		return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
	}

	decodeBase64(data) {
		return CryptoJS.enc.Base64.parse(CryptoJS.enc.Utf8.parse(data))
	}

	//md5运算
	md5(data) {
		try {
			return CryptoJS.MD5(data).toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1058', msg:'encrypt data failed'}
		}
	}

	sha1(data) {
		try {
			return CryptoJS.SHA1(data).toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1055', msg:'encrypt data failed'}
		}
	}

	sha256(data) {
		try {
			return CryptoJS.SHA256(data).toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1056', msg:'encrypt data failed'}
		}
	}

	sha512(data) {
		try {
			return CryptoJS.SHA512(data).toString()
		}
		catch(err) {
			console.error(err)
			throw {code:'-1056', msg:'encrypt data failed'}
		}
	}

}

module.exports = crypto